#include <iostream>
#include <iostream>
#include <string>
#include <memory>
#include <cstring>
#include <unistd.h>
#include <cassert>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Thread.hpp"

static const int g_ip_port_size=64;

static void *sendFunc(void *args) // 发送数据
{
    ThreadData *ptd=(ThreadData *)args;

    // 获取服务器的IP和PORT
    char ip[g_ip_port_size];
    memset(ip,0,sizeof(ip));
    uint16_t port;

    sscanf((char *)ptd->_objThis,"%s%d",ip,&port);

    struct sockaddr_in server;
    memset(&server,0,sizeof(server));
    server.sin_family=AF_INET;
    server.sin_addr.s_addr=inet_addr(ip);
    server.sin_port=htons(port);

    socklen_t server_len=sizeof(server);

    std::string message;
    while(true)
    {
        std::cerr<<"请输入:";
        getline(std::cin,message);

        sendto(ptd->_number,message.c_str(),message.size(),0,(struct sockaddr *)&server,server_len);
    }
}

static void *recvFunc(void *args) // 接收数据
{
    ThreadData *ptd=(ThreadData *)args;
    struct sockaddr_in server;
    memset(&server,0,sizeof(server));
    socklen_t server_len=sizeof(server);

    char buff[1024];
    while(true)
    {
        ssize_t n=recvfrom(ptd->_number,buff,sizeof(buff)-1,0,(struct sockaddr *)&server,&server_len);
        buff[n]='\0';

        std::cout<<buff<<std::endl;
    }
}

// 将客户端改为多线程,recver进行接收数据,send进行发送数据
int main(int argc,char *argv[],char *env[])
{
    if(argc!=3)
    {
        fprintf(stdout,"\n./servec_udp ip port\n\n");
        exit(1);
    }
    
    std::string ip=argv[1];
    uint16_t port=atoi(argv[2]);

    char* ip_port=new char[g_ip_port_size];
    assert(ip_port!=nullptr);
    snprintf(ip_port,g_ip_port_size-1,"%s %hd",ip.c_str(),port);

    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    assert(sockfd>=0);

    std::unique_ptr<Thread> sender(new Thread(sockfd,sendFunc,(void *)ip_port));
    std::unique_ptr<Thread> recver(new Thread(sockfd,recvFunc,(void *)ip_port));
    
    sender->Create();
    recver->Create();

    sender->Join();
    recver->Join();

    delete[] ip_port;
    return 0;
}

// //单线程无法满足群聊
// int main(int argc,char *argv[],char *env[])
// {
//     if(argc!=3)
//     {
//         fprintf(stdout,"\n./servec_udp ip port\n\n");
//         exit(1);
//     }
    
//     std::string ip=argv[1];
//     uint16_t port=atoi(argv[2]);

//     // 创建套接字
//     int sock=socket(AF_INET,SOCK_DGRAM,0);

//     struct sockaddr_in server;
//     memset(&server,0,sizeof(server));
//     server.sin_family=AF_INET;
//     server.sin_port=htons(port);
//     server.sin_addr.s_addr=inet_addr(ip.c_str());

//     socklen_t slen=sizeof(server);
//     std::string message;

//     char buff[1024];
//     for(;;)
//     {
//         std::cout<<"请输入:";
//         std::getline(std::cin,message);

//         // 客服端发送请求后 
//         sendto(sock,message.c_str(),message.size(),0,(struct sockaddr*)&server,slen);
//         // 获取服务端的响应
//         ssize_t n=recvfrom(sock,(void *)buff,sizeof(buff)-1,0,nullptr,nullptr);
//         assert(n>=0);
//         buff[n]='\0';

//         std::cout<<buff<<std::endl;
//     }

//     return 0;
// }